package com.content.scaffold.common.handler;

import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.AES;
import com.content.scaffold.common.properties.EncryptProperties;
import com.content.scaffold.common.utils.SpringContextHolder;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * @author xiaojl
 */
public class AesEncryptHandler extends BaseTypeHandler<String> {
    private static final AES AES;
    static {
        String key = SpringContextHolder.getBean(EncryptProperties.class).getKey();
        byte[] key2 = SecureUtil.decode(key);
        AES = SecureUtil.aes(key2);
    }
   /** public AesEncryptHandler(EncryptProperties properties) {
        String key = SpringContextHolder.getBean(EncryptProperties.class).getKey();
        byte[] key2 = SecureUtil.decode(key);
        this.aes = SecureUtil.aes(key2);
    }**/

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
        // 存储时加密
        try {
            ps.setString(i, AES.encryptHex(parameter));
        } catch (Exception e) {

            throw new SQLException("Failed to encrypt data", e);
        }
    }

    @Override
    public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String encryptedValue = rs.getString(columnName);
        if (StringUtils.isEmpty(encryptedValue)) {
            return null;
        }
        try {
            return AES.decryptStr(encryptedValue);
        } catch (Exception e) {
            // 记录异常以便排查问题
            System.err.println("Decryption failed for column: " + columnName);
            throw new SQLException("Failed to decryptStr data", e);
        }
    }

    @Override
    public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        String encryptedValue = rs.getString(columnIndex);
        if (StringUtils.isEmpty(encryptedValue)) {
            return null;
        }
        try {
            return AES.decryptStr(encryptedValue);
        } catch (Exception e) {
            System.err.println("Decryption failed for column index: " + columnIndex);
            throw new SQLException("Failed to decryptStr data", e);
        }
    }

    @Override
    public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        String encryptedValue = cs.getString(columnIndex);
        if (StringUtils.isEmpty(encryptedValue)) {
            return null;
        }
        try {
            return AES.decryptStr(encryptedValue);
        } catch (Exception e) {
            System.err.println("Decryption failed for callable statement column index: " + columnIndex);
            throw new SQLException("Failed to decryptStr data", e);
        }
    }
}
